/*
 * Copyright (c) 2018-2999 北京小象智慧信息科技有限公司 All rights reserved.
 *
 * https://www.xiaoxiangai.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;

import java.math.BigDecimal;
import java.util.*;

import javax.validation.Valid;

import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.app.param.OrderItemParam;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.event.ConfirmOrderEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.app.param.OrderShopParam;
import com.yami.shop.bean.app.param.SubmitOrderParam;
import com.yami.shop.common.util.Arith;

import cn.hutool.core.collection.CollectionUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;

@RestController
@RequestMapping("/p/order")
@Api(tags = "订单接口")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserAddrService userAddrService;
    @Autowired
    private BasketService basketService;
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private CouponRecordService couponRecordService;

    @Autowired
    private CouponService couponService;
    @Autowired
    private ShopDetailService shopDetailService;




    /**
     * 拼团商品生成订单
     * */
    @GetMapping("/groupOrderConfirm")
    @ApiOperation(value = "拼团商品生成订单",notes = "传入下单所需要的参数进行下单")
    public ResponseEntity<Order> groupOrderConfirm(@Valid @RequestBody OrderParam orderParam){
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(orderParam.getShopId());
        Order order = new Order();
        String userId = SecurityUtils.getUser().getUserId();
        order.setUserId(userId);
        // 订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        UserAddrDto userAddrDto = mapperFacade.map(userAddr, UserAddrDto.class);
        order.setAddrOrderId(orderParam.getAddrId());
        order.setProductNums(1);//订单数量 拼团订单数量都是1
        order.setIsPayed(0);//没有支付过
        order.setDeleteStatus(0);//用户订单删除状态，0：没有删除， 1：回收站， 2：永久删除
        order.setShopName(shopDetail.getShopName());
        orderService.insertOrder(order);
        return ResponseEntity.ok(order);
    }

    /**
     * 生成订单
     */
    @PostMapping("/confirm")
    @ApiOperation(value = "结算，生成订单信息", notes = "传入下单所需要的参数进行下单")
    public ResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
        String userId = SecurityUtils.getUser().getUserId() ;

        // 订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        UserAddrDto userAddrDto = mapperFacade.map(userAddr, UserAddrDto.class);

        // 组装获取用户提交的购物车商品项
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItemsByOrderItems(orderParam.getBasketIds(),orderParam.getOrderItem(),userId,orderParam.getShopId());

        if (CollectionUtil.isEmpty(shopCartItems)) {
            throw new YamiShopBindException("请选择您需要的商品加入购物车");
        }

        // 根据店铺组装购车中的商品信息，返回每个店铺中的购物车商品信息
        List<ShopCartDto> shopCarts = basketService.getShopCarts(shopCartItems);

        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();

        shopCartOrderMergerDto.setUserAddr(userAddrDto);

        // 所有店铺的订单信息
        List<ShopCartOrderDto> shopCartOrders = new ArrayList<>();

        double actualTotal = 0.0;
        double total = 0.0;
        int totalCount = 0;
        double orderReduce = 0.0;

//        List<CouponOrderDto> coupons = new ArrayList<>();
        CouponRecord couponRecord = new CouponRecord();
        for (ShopCartDto shopCart : shopCarts) {

            // 每个店铺的订单信息
            ShopCartOrderDto shopCartOrder = new ShopCartOrderDto();
            shopCartOrder.setShopId(shopCart.getShopId());
            shopCartOrder.setShopName(shopCart.getShopName());

            couponRecord.setShopId(shopCart.getShopId());


            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();

            // 店铺中的所有商品项信息
            List<ShopCartItemDto> shopAllShopCartItems = new ArrayList<>();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> discountShopCartItems = shopCartItemDiscount.getShopCartItems();
                shopAllShopCartItems.addAll(discountShopCartItems);
            }

            shopCartOrder.setShopCartItemDiscounts(shopCartItemDiscounts);

            applicationContext.publishEvent(new ConfirmOrderEvent(shopCartOrder,orderParam,shopAllShopCartItems));

            actualTotal = Arith.add(actualTotal,shopCartOrder.getActualTotal());
            total = Arith.add(total,shopCartOrder.getTotal());
            totalCount = totalCount + shopCartOrder.getTotalCount();
            orderReduce = Arith.add(orderReduce,shopCartOrder.getShopReduce());
            shopCartOrders.add(shopCartOrder);

        }

        // 店铺优惠券列表
        int couponKind = 1;
        List<CouponDto> couponList = couponService.getAllCoupon(orderParam.getShopId(),null,userId,couponKind);
        // 支付金额
        BigDecimal money = new BigDecimal(actualTotal);
        List<CouponDto> optimumList = null;
        if(couponList.size()>0){
            optimumList = basketService.getOptimumList(couponList, money);
        }

        if(optimumList!=null){
            double reduceMoney = optimumList.get(0).getFullAmountReduce();
            BigDecimal data1 = new BigDecimal(reduceMoney);
            if(data1.compareTo(money)>0){

            }else {
                actualTotal = Arith.sub(actualTotal,reduceMoney);
                orderReduce = Arith.add(orderReduce,reduceMoney);
                shopCartOrders.get(0).setShopRecordId(optimumList.get(0).getRecordId());
            }
        }else {

        }

        shopCartOrderMergerDto.setActualTotal(actualTotal);
        shopCartOrderMergerDto.setTotal(total);
        shopCartOrderMergerDto.setTotalCount(totalCount);
        shopCartOrderMergerDto.setShopCartOrders(shopCartOrders);
        shopCartOrderMergerDto.setOrderReduce(orderReduce);

        if(orderParam.getBasketIds()==null){
            couponRecord.setUserId(userId);
            couponRecord.setProdId(orderParam.getOrderItem().getProdId());
            List<CouponRecordDto> couponRecordList = couponRecordService.selectUseCouponRecord(couponRecord);
            shopCartOrderMergerDto.setCouponRecords(couponRecordList);
        }


        orderService.putConfirmOrderCache(userId,shopCartOrderMergerDto);

        return ResponseEntity.ok(shopCartOrderMergerDto);
    }

    /**
     * 计算店铺优惠券，平台优惠券 优惠后金额
     */
    @PostMapping("/favourMoney")
    @ApiOperation(value = "计算优惠后金额", notes = "传入计算所需要的参数进行计算")
    public ResponseEntity<ShopCartOrderMergerDto> favourMoney(@Valid @RequestBody OrderParam orderParam) {

        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();

        OrderItemParam orderItemParam = orderParam.getOrderItem();
        Long prodId = orderItemParam.getProdId();
        Long skuId = orderItemParam.getSkuId();
        Long shopId = orderItemParam.getShopId();
        Long recordId = orderItemParam.getRecordId();
        Integer prodCount = orderItemParam.getProdCount();

        Sku sku = skuService.getSkuBySkuId(skuId);
        if (sku == null) {
            throw new RuntimeException("订单包含无法识别的商品");
        }
        Product prod = productService.getProductByProdId(prodId);
        if (prod == null) {
            throw new RuntimeException("订单包含无法识别的商品");
        }

        double price = sku.getPrice();
        //支付金额
        BigDecimal money = new BigDecimal(Arith.mul(price,prodCount));
        List<CouponRecordDto> couponRecordDtoList = couponRecordService.getCouponAndRecord(recordId);
        if(CollectionUtils.isEmpty(couponRecordDtoList)){
            throw new RuntimeException("请选择优惠券");
        }
        //优惠券类型 0：无门槛券     1：满减券
        int couponType = couponRecordDtoList.get(0).getCouponType();
        double productTotalAmount = 0;
        double actualTotal = 0.0;
        double total = 0.0;
        int totalCount = 0;
        double orderReduce = 0.0;
        //满减金额
        double reduceMoney;
        //优惠券金额
        double fullAmountReduce;
        if(couponType == 0){
            double fullReduceMoney = couponRecordDtoList.get(0).getFullAmountReduce();
            BigDecimal data1 = new BigDecimal(fullReduceMoney);
            if(data1.compareTo(money)>0){
                throw new YamiShopBindException("不符合使用条件，请选择其他优惠券");
            }else {
                fullAmountReduce = couponRecordDtoList.get(0).getFullAmountReduce();
                productTotalAmount = Arith.sub(money.doubleValue(), fullAmountReduce);
                orderReduce = Arith.add(orderReduce, fullAmountReduce);
            }
        }else{
            reduceMoney = couponRecordDtoList.get(0).getReduceMoney();
            fullAmountReduce = couponRecordDtoList.get(0).getFullAmountReduce();
            if(new BigDecimal(reduceMoney).compareTo(money)>0){
                productTotalAmount = money.doubleValue();
                orderReduce = Arith.add(orderReduce,reduceMoney);
            }else{
                productTotalAmount = Arith.sub(money.doubleValue(),fullAmountReduce);
                orderReduce = Arith.add(orderReduce,fullAmountReduce);
            }
        }

        actualTotal = Arith.add(actualTotal,productTotalAmount);
        total = Arith.add(total,money.doubleValue());
        totalCount = totalCount + prodCount;

        String userId = SecurityUtils.getUser().getUserId();

        shopCartOrderMergerDto.setActualTotal(actualTotal);
        shopCartOrderMergerDto.setTotal(total);
        shopCartOrderMergerDto.setTotalCount(totalCount);
        shopCartOrderMergerDto.setOrderReduce(orderReduce);

        orderService.putConfirmOrderCache(userId,shopCartOrderMergerDto);

        return ResponseEntity.ok(shopCartOrderMergerDto);
    }


    /**
     * 购物车/立即购买  提交订单,根据店铺拆单
     */
    @PostMapping("/submit")
    @ApiOperation(value = "提交订单，返回支付流水号", notes = "根据传入的参数判断是否为购物车提交订单，同时对购物车进行删除，用户开始进行支付")
    public ResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody SubmitOrderParam submitOrderParam) {
        //获取推荐人信息

        String tjr = null;
        String pickupTime = null;
        String ptglid = null;
        String purchaseType = null;
        Long prodId = null;
        String userId = SecurityUtils.getUser().getUserId();
        ShopCartOrderMergerDto mergerOrder = orderService.getConfirmOrderCache(userId);
        if (mergerOrder == null) {
            throw new YamiShopBindException("订单已过期，请重新下单");
        }

        List<OrderShopParam> orderShopParams = submitOrderParam.getOrderShopParam();

        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        // 设置备注
        if (CollectionUtil.isNotEmpty(orderShopParams)) {
            tjr = submitOrderParam.getOrderShopParam().get(0).getTjr();
            ptglid = submitOrderParam.getOrderShopParam().get(0).getPtglid();
            purchaseType = submitOrderParam.getOrderShopParam().get(0).getPurchaseType();
            prodId = submitOrderParam.getOrderShopParam().get(0).getProdId();
            pickupTime = submitOrderParam.getOrderShopParam().get(0).getPickupTime();
            for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
                for (OrderShopParam orderShopParam : orderShopParams) {
                    if (Objects.equals(shopCartOrder.getShopId(), orderShopParam.getShopId())) {
                        shopCartOrder.setRemarks(orderShopParam.getRemarks());
                        if(orderShopParam.getDistributionType()!=null) {
                            shopCartOrder.setDistributionType(orderShopParam.getDistributionType());
                        }
                    }
                }
            }
        }

        List<Order> orders = orderService.submit(userId,mergerOrder,tjr,pickupTime,ptglid,purchaseType,prodId);



        StringBuilder orderNumbers = new StringBuilder();
        for (Order order : orders) {
            orderNumbers.append(order.getOrderNumber()).append(",");
        }
        orderNumbers.deleteCharAt(orderNumbers.length() - 1);

        boolean isShopCartOrder = false;
        // 移除缓存
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    Long basketId = shopCartItem.getBasketId();
                    if (basketId != null && basketId != 0) {
                        isShopCartOrder = true;
                    }
                    skuService.removeSkuCacheBySkuId(shopCartItem.getSkuId(),shopCartItem.getProdId());
                    productService.removeProductCacheByProdId(shopCartItem.getProdId());
                }
            }
        }
        // 购物车提交订单时(即有购物车ID时)
        if (isShopCartOrder) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        orderService.removeConfirmOrderCache(userId);
        return ResponseEntity.ok(new OrderNumbersDto(orderNumbers.toString()));
    }

    /**
     * 可用优惠券查询
     */
    @GetMapping("/couponInfo")
//    @PreAuthorize("@pms.hasPermission('coupon:coupon:info')")
    public ResponseEntity<List<CouponRecord>> couponInfo(Long shopId){
        CouponRecord couponRecord = new CouponRecord();
        couponRecord.setShopId(shopId);
        String userId = SecurityUtils.getUser().getUserId();
        couponRecord.setUserId(userId);
        List<CouponRecord> couponRecordList = couponRecordService.selectValidCoupon(couponRecord);
        return ResponseEntity.ok(couponRecordList);
    }

//    /**
//     * 退款
//     */
//    @PutMapping("/refund")
//    @PreAuthorize("@pms.hasPermission('p:order:refund')")
//    public ResponseEntity<Void> refund(@RequestBody OrderParam orderParam) throws Exception {
////        Long shopId = SecurityUtils.getSysUser().getShopId();
//        Order order = orderService.getOrderByOrderNumber(orderParam.getOrderNumber());
////        if (!com.google.common.base.Objects.equal(shopId, order.getShopId())) {
////            throw new YamiShopBindException("您没有权限修改该订单信息");
////        }
//
//        Order orderParam1 = new Order();
//        orderParam1.setOrderId(order.getOrderId());
//        orderParam1.setDvyTime(new Date());
//        orderParam1.setStatus(OrderStatus.REFUND.value());
//        orderParam1.setUserId(order.getUserId());
//        /**
//         * 当未发货时可直接退款
//         */
//        int state=order.getStatus();
//        String orderNumber = orderParam.getOrderNumber();
//        if(state==2){
//         //   RefundController refundController = new RefundController();
//          //  refundController.refund(order.getOrderNumber());
//            /**
//             * 直接退款时将退款状态改为8（退款成功）
//             */
//            orderService.updateRefund(orderNumber,8);
//            return ResponseEntity.ok().build();
//        }
//
//        /**
//         * 已发货时需要后台审核申请
//         */
//        orderService.refund(orderParam1);
//
//        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderParam.getOrderNumber());
//        for (OrderItem orderItem : orderItems) {
//            productService.removeProductCacheByProdId(orderItem.getProdId());
//            skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId());
//        }
//        return ResponseEntity.ok().build();
//    }

    /**
     * 获取再次购买订单的item
     */
    @GetMapping("/buyAgain")
    public ResponseEntity<Map> buyAgain(String orderNumber){
        Map map = new HashMap();
        List<Long> list = new ArrayList();
        //根据订单查询
        List<OrderItem> orderItemList = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        //获取店铺ID
        Order order = orderService.getOrderByOrderNumber(orderNumber);
        Long orderShopNumber = order.getShopId();
        map.put("shopId",orderShopNumber);
        if(null!=orderItemList){
            for(OrderItem orderItem:orderItemList){
                Basket basket = new Basket();
                //获取店铺Id
                Long shopId = orderItem.getShopId();
                //获取商品ID
                Long prodId = orderItem.getProdId();
                //skuId
                Long skuId = orderItem.getSkuId();
                //userId
                String userId = orderItem.getUserId();
                //number
                int prodCount = orderItem.getProdCount();
                basket.setShopId(shopId);
                basket.setProdId(prodId);
                basket.setSkuId(skuId);
                basket.setUserId(userId);
                basket.setBasketCount(prodCount);
                basket.setBasketDate(new Date());
                //根据产品ID sku查看购物车有没有商品.如果有的话，进行累加,返回basketId
                Basket currentBasket = basketService.getBasketByProdId(basket);
                if(null!=currentBasket){
                    int sum =prodCount + currentBasket.getBasketCount();
                    currentBasket.setBasketCount(sum);
                    basketService.updateById(currentBasket);
                    list.add(currentBasket.getBasketId());
                }else{
                    basketService.save(basket);
                    list.add(basket.getBasketId());
                }

            }
        }
        map.put("basketList",list);
        return ResponseEntity.ok(map);
    }




}
